home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / comm / vt100r29.4 < prev    next >
Internet Message Format  |  1989-10-20  |  41KB

  1. Path: xanth!mcnc!rutgers!ucsd!tut.cis.ohio-state.edu!mailrus!ames!sun-barr!newstop!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i181:  vt100 - terminal emulator v2.9, Part04/09
  5. Message-ID: <126579@sun.Eng.Sun.COM>
  6. Date: 20 Oct 89 06:10:10 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1821
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: acs@pccuts.pcc.amdahl.com (Tony Sumrall)
  12. Posting-number: Volume 89, Issue 181
  13. Archive-name: comm/vt100r29.4
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    Zmodem/rz.c
  24. # This is archive 4 of a 9-part kit.
  25. # This archive created: Thu Oct 19 22:30:30 1989
  26. if `test ! -d Zmodem`
  27. then
  28.   mkdir Zmodem
  29.   echo "mkdir Zmodem"
  30. fi
  31. echo "extracting Zmodem/rz.c"
  32. sed 's/^X//' << \SHAR_EOF > Zmodem/rz.c
  33. X#define VERSION "1.26 08-21-87"
  34. X#define PUBDIR "/usr/spool/uucppublic"
  35. X
  36. X/*% cc -M0 -Ox -K -i % -o rz; size rz;
  37. X<-xtx-*> cc386 -Ox rz.c -o $B/rz;  size $B/rz
  38. X *
  39. X * rz.c By Chuck Forsberg
  40. X *
  41. X *    cc -O rz.c -o rz        USG (3.0) Unix
  42. X *    cc -O -DV7  rz.c -o rz        Unix V7, BSD 2.8 - 4.3
  43. X *
  44. X *    ln rz rb;  ln rz rx            For either system
  45. X *
  46. X *    ln rz /usr/bin/rzrmail        For remote mail.  Make this the
  47. X *                    login shell. rzrmail then calls
  48. X *                    rmail(1) to deliver mail.
  49. X *
  50. X *
  51. X * Amiga version by Frank Harper using Aztec C 3.4b
  52. X *
  53. X *    cc +L rz.c;cc +L SerIO.c;cc +L term.c;ln rz.o SerIO.o term.o -lc32
  54. X *    or just use the makefile
  55. X *
  56. X * See Amiga.doc for more details on Amiga version
  57. X *
  58. X *  Unix is a trademark of Western Electric Company
  59. X *
  60. X * A program for Unix to receive files and commands from computers running
  61. X *  Professional-YAM, PowerCom, YAM, IMP, or programs supporting XMODEM.
  62. X *  rz uses Unix buffered input to reduce wasted CPU time.
  63. X *
  64. X * Iff the program is invoked by rzCOMMAND, output is piped to
  65. X * "COMMAND filename"
  66. X *
  67. X *  Some systems (Venix, Coherent, Regulus) may not support tty raw mode
  68. X *  read(2) the same way as Unix. ONEREAD must be defined to force one
  69. X *  character reads for these systems. Added 7-01-84 CAF
  70. X *
  71. X *  Alarm signal handling changed to work with 4.2 BSD 7-15-84 CAF
  72. X *
  73. X *  BIX added 6-30-87 to support BIX(TM) upload protocol used by the
  74. X *  Byte Information Exchange.
  75. X *
  76. X *  NFGVMIN Updated 2-18-87 CAF for Xenix systems where c_cc[VMIN]
  77. X *  doesn't work properly (even though it compiles without error!),
  78. X *
  79. X *  HOWMANY may be tuned for best performance
  80. X *
  81. X *  USG UNIX (3.0) ioctl conventions courtesy  Jeff Martin
  82. X */
  83. X#ifdef AMIGA
  84. X#define LOGFILE "rzlog"
  85. X#include <time.h>
  86. X#include <stdio.h>
  87. X#include <ctype.h>
  88. X#include <stat.h>
  89. X#include <devices/timer.h>
  90. X#include <devices/serial.h>
  91. X#include <libraries/dos.h>
  92. X#include "intuition/intuition.h"
  93. X#include <exec/memory.h>
  94. X
  95. X#define RZ
  96. X
  97. Xvoid *OpenLibrary();
  98. Xstruct Window *OpenWindow();
  99. X
  100. Xstruct IntuitionBase *IntuitionBase;
  101. Xstruct NewWindow nw = {
  102. X   0, 0,         /* start position            */
  103. X   640, 120,         /* width, height            */
  104. X   -1, -1,         /* detail pen, block pen        */
  105. X   CLOSEWINDOW,      /* IDCMP flags            */
  106. X   ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING | WINDOWCLOSE
  107. X   | NOCAREREFRESH,  /* window flags            */
  108. X   NULL,         /* pointer to first user gadget    */
  109. X   NULL,         /* pointer to user checkmark    */
  110. X   (UBYTE *)"Rz",    /* window title                    */
  111. X   NULL,         /* pointer to screen    (later)    */
  112. X   NULL,         /* pointer to superbitmap        */
  113. X   50,40,-1,-1,      /* sizing limits min and max    */
  114. X   WBENCHSCREEN      /* type of screen in which to open */
  115. X   };
  116. Xint InitSer = FALSE;
  117. Xint gmt_diff_set=FALSE; /* Has GMT offset been set? */
  118. Xint gmt_diff;        /* Local offset from GMT time */
  119. Xint SetProtect=TRUE;
  120. Xint Term=FALSE;     /* Use Terminal mode ? */
  121. Xint WaitC=TRUE;     /* Wait for confirmation before closing window?*/
  122. Xstruct IOStdReq *ConWriteReq, *ConReadReq;
  123. Xstruct Window *Win;
  124. Xstruct MsgPort    *ConReadPort,*ConWritePort;
  125. Xint WinOutPut;
  126. Xint FullDuplex=TRUE;
  127. Xstruct IOExtSer *InSer, *OutSer;
  128. Xstruct MsgPort    *InSerPort, *OutSerPort;
  129. XULONG  InSerSigMask, OutSerSigMask;
  130. XUBYTE  SerOpen;
  131. Xstruct timerequest *IOTime;
  132. Xstruct MsgPort *TimerPort;
  133. XULONG  IOTimeSigMask;
  134. X
  135. Xint Skip=TRUE;        /* Skip files which are to big to fit on disk */
  136. X#else
  137. X#define LOGFILE "/tmp/rzlog"
  138. X
  139. X#include <stdio.h>
  140. X#include <signal.h>
  141. X#include <setjmp.h>
  142. X#include <ctype.h>
  143. XFILE *popen();
  144. X#endif
  145. X
  146. X#define OK 0
  147. X
  148. X#ifndef AMIGA /* Already defined in <exec/types.h> */
  149. X#define FALSE 0
  150. X#define TRUE 1
  151. X#endif
  152. X
  153. X#define ERROR (-1)
  154. X
  155. X/*
  156. X * Max value for HOWMANY is 255.
  157. X *   A larger value reduces system overhead but may evoke kernel bugs.
  158. X *   133 corresponds to an XMODEM/CRC sector
  159. X *
  160. X * This isn't used in Amiga version
  161. X */
  162. X#ifndef HOWMANY
  163. X#define HOWMANY 133
  164. X#endif
  165. X
  166. Xint Zmodem=0;        /* ZMODEM protocol requested */
  167. Xint Nozmodem = 0;    /* If invoked as "rb" */
  168. Xunsigned Baudrate;
  169. X
  170. Xchar *substr();
  171. XFILE *fout;
  172. X
  173. X/* Ward Christensen / CP/M parameters - Don't change these! */
  174. X#define ENQ 005
  175. X#define CAN ('X'&037)
  176. X#define XOFF ('s'&037)
  177. X#define XON ('q'&037)
  178. X#define SOH 1
  179. X#define STX 2
  180. X#define EOT 4
  181. X#define ACK 6
  182. X#define NAK 025
  183. X#define CPMEOF 032
  184. X#define WANTCRC 0103    /* send C not NAK to get crc not checksum */
  185. X#define TIMEOUT (-2)
  186. X#define RCDO (-3)
  187. X#define ERRORMAX 5
  188. X#define RETRYMAX 5
  189. X#define WCEOT (-10)
  190. X#define SECSIZ 128    /* cp/m's Magic Number record size */
  191. X#define PATHLEN 257    /* ready for 4.2 bsd ? */
  192. X#define KSIZE 1024    /* record size with k option */
  193. X#define UNIXFILE 0x8000 /* happens to the the S_IFREG file mask bit for stat */
  194. X
  195. Xint Lastrx;
  196. Xint Crcflg;
  197. Xint Firstsec;
  198. Xint Eofseen;        /* indicates cpm eof (^Z) has been received */
  199. Xint errors;
  200. Xint Restricted=0;    /* restricted; no /.. or ../ in filenames */
  201. X#ifdef ONEREAD
  202. X/* Sorry, Regulus and some others don't work right in raw mode! */
  203. Xint Readnum = 1;    /* Number of bytes to ask for in read() from modem */
  204. X#else
  205. Xint Readnum = HOWMANY;    /* Number of bytes to ask for in read() from modem */
  206. X#endif
  207. X
  208. X#define DEFBYTL 2000000000L    /* default rx file size */
  209. Xlong Bytesleft;     /* number of bytes of incoming file left */
  210. Xlong Modtime;        /* Unix style mod time for incoming file */
  211. X#ifndef AMIGA
  212. Xshort Filemode;     /* Unix style mode for incoming file */
  213. X#else
  214. Xint Filemode;        /* This avoids a problem with the sscanf used to
  215. X                read Filemode */
  216. X#endif
  217. Xchar Pathname[PATHLEN];
  218. Xchar *Progname;     /* the name by which we were called */
  219. X
  220. Xint Batch=0;
  221. Xint Wcsmask=0377;
  222. Xint Topipe=0;
  223. Xint MakeLCPathname=TRUE;    /* make received pathname lower case */
  224. Xint Verbose=0;
  225. Xint Quiet=0;        /* overrides logic that would otherwise set verbose */
  226. Xint Nflag = 0;        /* Don't really transfer files */
  227. Xint Rxbinary=FALSE;    /* receive all files in bin mode */
  228. Xint Rxascii=FALSE;    /* receive files in ascii (translate) mode */
  229. Xint Thisbinary;     /* current file is to be received in bin mode */
  230. Xint Blklen;        /* record length of received packets */
  231. Xchar secbuf[KSIZE+1];
  232. Xchar linbuf[HOWMANY];
  233. Xint Lleft=0;        /* number of characters in linbuf */
  234. Xtime_t timep[2];
  235. Xchar Lzmanag;        /* Local file management request */
  236. Xchar zconv;        /* ZMODEM file conversion request */
  237. Xchar zmanag;        /* ZMODEM file management request */
  238. Xchar ztrans;        /* ZMODEM file transport request */
  239. Xint Zctlesc;        /* Encode control characters */
  240. Xint Zrwindow = 1400;    /* RX window size (controls garbage count) */
  241. X
  242. X#ifndef AMIGA
  243. Xjmp_buf tohere;     /* For the interrupt on RX timeout */
  244. X#endif
  245. X
  246. X#include "rbsb.c"       /* most of the system dependent stuff here */
  247. X#include "zm.c"
  248. X
  249. Xint tryzhdrtype=ZRINIT; /* Header type to send corresponding to Last rx close */
  250. X
  251. X#ifndef AMIGA
  252. X/*
  253. X * Routine to calculate the free bytes on the current file system
  254. X *  ~0 means many free bytes (unknown)
  255. X */
  256. Xlong getfree()
  257. X{
  258. X    return(~0L);    /* many free bytes ... */
  259. X}
  260. X#else
  261. Xstruct DPTR {             /* Format of directory fetch pointer */
  262. X   struct FileLock *lock;     /* lock on directory    */
  263. X   struct FileInfoBlock *fib;     /* mod'd fib for entry */
  264. X};
  265. X
  266. Xstruct DPTR *dopen();
  267. Xstruct FileLock *Lock();
  268. Xstruct FileLock *ParentDir();
  269. Xstruct MsgPort *DeviceProc();
  270. Xvoid *AllocMem();
  271. Xvoid *malloc();
  272. X
  273. X /*
  274. X  * Calculate free bytes on current file system
  275. X  * ~0L means number of free bytes unknown
  276. X  * Adapted from shell 2.07's devinfo routine (Thanks Matt & Steve)
  277. X  */
  278. X
  279. Xlong getfree()
  280. X{
  281. X   struct DPTR        *dp;
  282. X   struct InfoData    *info;
  283. X   int stat;
  284. X   long retc;
  285. X
  286. X   if ((dp = dopen ("", &stat))!=NULL) {
  287. X     info = (struct InfoData *)AllocMem((long)sizeof(struct InfoData), MEMF_PUBLIC);
  288. X     if (Info (dp->lock, info))
  289. X       retc=(info->id_NumBlocks - info->id_NumBlocksUsed)*512; /* assume 512 byte blocks */
  290. X     else  {
  291. X    if(Verbose) fprintf(stderr,"getfree failed\n");
  292. X    retc=~0L;
  293. X     }
  294. X   }
  295. X   FreeMem (info,(long) sizeof(*info));
  296. X   dclose(dp);
  297. X   if(Verbose) fprintf(stderr,"%ld bytes free on disk\n",retc);
  298. X   return(retc);
  299. X}
  300. X
  301. X /*
  302. X  * Change a files date
  303. X  * Lifted from Shell 2.07
  304. X  *
  305. X  */
  306. X
  307. Xfile_date(date,name)
  308. Xstruct DateStamp *date;
  309. Xchar *name;
  310. X{
  311. X    UBYTE *ptr;
  312. X    struct MsgPort *task;
  313. X    struct FileLock *dirlock;
  314. X    struct DPTR *tmp;
  315. X    int stat;
  316. X    long ret, dos_packet();
  317. X
  318. X    if (!(task = (struct MsgPort *)DeviceProc(name)))
  319. X    return(1);
  320. X    if (tmp = dopen(name, &stat)) {
  321. X    dirlock = (struct FileLock *)ParentDir(tmp->lock);
  322. X    ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC);
  323. X    strcpy((ptr + 1),tmp->fib->fib_FileName);
  324. X    *ptr = strlen(tmp->fib->fib_FileName);
  325. X    dclose(tmp);
  326. X    ret = dos_packet(task,34L,NULL,dirlock,
  327. X             (ULONG)&ptr[0] >> 2L,date);
  328. X    FreeMem(ptr,64L);
  329. X    UnLock(dirlock);
  330. X    }
  331. X}
  332. X
  333. X/*
  334. X * These routines come directly from shell 2.07 by Matt Dillon,
  335. X * Manx version by Steve Drew.
  336. X *
  337. X * Disk directory routines
  338. X *
  339. X * dptr = dopen(name, stat)
  340. X *    struct DPTR *dptr;
  341. X *    char *name;
  342. X *    int *stat;
  343. X *
  344. X * dclose(dptr)                  -may be called with NULL without harm
  345. X *
  346. X * dopen() returns a struct DPTR, or NULL if the given file does not
  347. X * exist.  stat will be set to 1 if the file is a directory.  If the
  348. X * name is "", then the current directory is opened.
  349. X *
  350. X * dclose() closes a directory channel.
  351. X *
  352. X */
  353. X
  354. Xstruct DPTR *dopen(name, stat)
  355. Xchar *name;
  356. Xint *stat;
  357. X{
  358. X   struct DPTR *dp;
  359. X   int i;
  360. X
  361. X   *stat = 0;
  362. X   dp = (struct DPTR *)malloc(sizeof(struct DPTR));
  363. X   dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
  364. X   if (dp->lock == NULL) {
  365. X      free (dp);
  366. X      if(Verbose) fprintf(stderr,"Couldn't lock dir\n");
  367. X      return (NULL);
  368. X   }
  369. X   dp->fib = (struct FileInfoBlock *)
  370. X     AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
  371. X   if (!Examine (dp->lock, dp->fib)) {
  372. X      if(Verbose) fprintf(stderr,"dopen: Can't open current dir\n");
  373. X      dclose (dp);
  374. X      return (NULL);
  375. X   }
  376. X   if (dp->fib->fib_DirEntryType >= 0)
  377. X      *stat = 1;
  378. X   return (dp);
  379. X}
  380. X
  381. Xdclose(dp)
  382. Xstruct DPTR *dp;
  383. X{
  384. X   if (dp == NULL)
  385. X      return (1);
  386. X   if (dp->fib)
  387. X      FreeMem (dp->fib,(long)sizeof(*dp->fib));
  388. X   if (dp->lock)
  389. X      UnLock (dp->lock);
  390. X   free (dp);
  391. X   return (1);
  392. X}
  393. Xbibi(n)
  394. X{
  395. X    if (Zmodem)
  396. X    zmputs(Attn);
  397. X    flushmo();
  398. X    canit(); mode(0);
  399. X    if(fout) fclose(fout);
  400. X    CleanUp();
  401. X    exit(128+n);
  402. X}
  403. X
  404. XWaitbibi(n)
  405. Xint n;
  406. X{
  407. X    ConPutChar(ConWriteReq,7);
  408. X    ConPutStr(ConWriteReq,"\nsz: Transfer aborted");
  409. X    if( WaitC ) WaitClose();
  410. X    bibi(n);
  411. X}
  412. X
  413. XWaitClose()
  414. X{
  415. X ULONG IntuiMask;
  416. X
  417. X    IntuiMask = 1 << (Win->UserPort->mp_SigBit);
  418. X    while(!CheckQuit()) Wait(IntuiMask);
  419. X}
  420. X
  421. XAmigaInit()
  422. X{
  423. X    IntuitionBase = (struct IntuitionBase *)
  424. X            OpenLibrary("intuition.library", 33L);
  425. X    if (IntuitionBase == NULL) {
  426. X    puts("Unable to open 1.2 or higher intuition.library");
  427. X    exit(1);
  428. X    }
  429. X    Win = OpenWindow(&nw);
  430. X    if ( Win == NULL ) {
  431. X    puts("Unable to open window");
  432. X    CleanUp();
  433. X    exit(1);
  434. X    }
  435. X    WinOutPut=TRUE;
  436. X    if( OpenConsole(&ConWriteReq,&ConReadReq,Win)) {
  437. X    puts("Couldn't open console");
  438. X    CleanUp();
  439. X    exit(1);
  440. X    }
  441. X}
  442. X
  443. XCleanUp()
  444. X{
  445. X    CloseConsole(ConReadReq,ConWriteReq);
  446. X    if( Win )         CloseWindow(Win);
  447. X    if(IntuitionBase) CloseLibrary(IntuitionBase);
  448. X}
  449. X
  450. X /*
  451. X  * Send output to window
  452. X  *
  453. X  */
  454. Xfprintf(f,s,a1,a2,a3,a4)
  455. XFILE *f;
  456. Xchar *s;
  457. Xchar *a1,*a2,*a3,*a4;
  458. X{
  459. X char buf[256];
  460. X
  461. X sprintf(buf,s,a1,a2,a3,a4);
  462. X if( WinOutPut ) ConPutStr(ConWriteReq,buf);
  463. X else fputs(buf,f);
  464. X}
  465. X#endif
  466. X
  467. X#ifndef AMIGA
  468. Xalrm()
  469. X{
  470. X    longjmp(tohere, -1);
  471. X}
  472. X/* called by signal interrupt or terminate to clean things up */
  473. Xbibi(n)
  474. X{
  475. X    if (Zmodem)
  476. X        zmputs(Attn);
  477. X    canit(); mode(0);
  478. X    fprintf(stderr, "rz: caught signal %d; exiting", n);
  479. X    exit(128+n);
  480. X}
  481. X#endif
  482. X
  483. Xmain(argc, argv)
  484. Xchar *argv[];
  485. X{
  486. X    register char *cp;
  487. X    register npats;
  488. X    char *virgin, **patts;
  489. X    char *getenv();
  490. X    int exitcode = 0;
  491. X
  492. X    Rxtimeout = 100;
  493. X#ifndef AMIGA
  494. X    setbuf(stderr, NULL);
  495. X    if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh")))
  496. X        Restricted=TRUE;
  497. X#endif
  498. X
  499. X    chkinvok(virgin=argv[0]);       /* if called as [-]rzCOMMAND set flag */
  500. X    npats = 0;
  501. X#ifdef AMIGA
  502. X    AmigaInit();
  503. X#endif
  504. X    while (--argc) {
  505. X        cp = *++argv;
  506. X        if (*cp == '-') {
  507. X            while( *++cp) {
  508. X                switch(*cp) {
  509. X                case '+':
  510. X                    Lzmanag = ZMAPND; break;
  511. X#ifndef AMIGA
  512. X                case '1':
  513. X                    iofd = 1; break;
  514. X#else
  515. X                case 'I':
  516. X                    InitSer = TRUE; break;
  517. X                case 'B':
  518. X                    Nozmodem = TRUE; break;
  519. X#endif
  520. X                case '7':
  521. X                    Wcsmask = 0177;
  522. X                case 'a':
  523. X                    Rxascii=TRUE;  break;
  524. X                case 'b':
  525. X                    Rxbinary=TRUE; break;
  526. X                case 'c':
  527. X                    Crcflg=TRUE; break;
  528. X                case 'D':
  529. X                    Nflag = TRUE; break;
  530. X                case 'e':
  531. X                    Zctlesc = 1; break;
  532. X#ifdef AMIGA
  533. X                case 'h':
  534. X                    FullDuplex = FALSE; break;
  535. X                case 'm':
  536. X                    SetProtect = FALSE; break;
  537. X                case 'n':
  538. X                    Skip = FALSE;  break;
  539. X#endif
  540. X                case 'p':
  541. X                    Lzmanag = ZMPROT;  break;
  542. X                case 'q':
  543. X                    Quiet=TRUE; Verbose=0; break;
  544. X#ifdef AMIGA
  545. X                case 'Q':
  546. X                    WaitC = FALSE; break;
  547. X#endif
  548. X                case 't':
  549. X                    if (--argc < 1) {
  550. X                        usage();
  551. X                    }
  552. X                    Rxtimeout = atoi(*++argv);
  553. X                    if (Rxtimeout<10 || Rxtimeout>1000)
  554. X                        usage();
  555. X                    break;
  556. X#ifdef AMIGA
  557. X                case 'T':
  558. X                    Term=TRUE; break;
  559. X#endif
  560. X                case 'w':
  561. X                    if (--argc < 1) {
  562. X                        usage();
  563. X                    }
  564. X                    Zrwindow = atoi(*++argv);
  565. X                    break;
  566. X                case 'u':
  567. X                    MakeLCPathname=FALSE; break;
  568. X                case 'v':
  569. X                    ++Verbose; break;
  570. X                default:
  571. X                    usage();
  572. X                }
  573. X            }
  574. X        }
  575. X        else if ( !npats && argc>0) {
  576. X            if (argv[0][0]) {
  577. X                npats=argc;
  578. X                patts=argv;
  579. X            }
  580. X        }
  581. X    }
  582. X    if (npats > 1)
  583. X        usage();
  584. X#ifdef AMIGA
  585. X    if( mode(1)==ERROR) {
  586. X        fprintf(stderr,"Couldn't initialize serial port\n");
  587. X        Waitbibi(1);
  588. X    }
  589. X    if (Term) {
  590. X        fprintf(stderr,"Entering terminal mode, click on close box when ready to start file transfer\n");
  591. X        term();
  592. X    }
  593. X#endif
  594. X    if (Verbose) {
  595. X        if (freopen(LOGFILE, "a", stderr)==NULL) {
  596. X            printf("Can't open log file %s\n",LOGFILE);
  597. X            exit(0200);
  598. X        }
  599. X        setbuf(stderr, NULL);
  600. X#ifdef AMIGA
  601. X        WinOutPut=FALSE;
  602. X#endif
  603. X        fprintf(stderr, "argv[0]=%s Progname=%s\n", virgin, Progname);
  604. X    }
  605. X    if (fromcu() && !Quiet) {
  606. X        if (Verbose == 0)
  607. X            Verbose = 2;
  608. X    }
  609. X#ifndef AMIGA
  610. X    mode(1);
  611. X    if (signal(SIGINT, bibi) == SIG_IGN) {
  612. X        signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN);
  613. X    }
  614. X    else {
  615. X        signal(SIGINT, bibi); signal(SIGKILL, bibi);
  616. X    }
  617. X    signal(SIGTERM, bibi);
  618. X#endif
  619. X    if (wcreceive(npats, patts)==ERROR) {
  620. X        exitcode=0200;
  621. X        canit();
  622. X#ifdef AMIGA
  623. X        fprintf(stderr,"\n\007File transfer failed\n");
  624. X#endif
  625. X    }
  626. X#ifdef AMIGA
  627. X    else fprintf(stderr,"\nFile transfer succesful\n");
  628. X    if (Term) {
  629. X        fprintf(stderr,"Re-entering terminal mode. Click on close box to exit Rz.\n");
  630. X        term();
  631. X    }
  632. X    else if( WaitC ) {
  633. X        fprintf(stderr,"Click on close box to exit Rz\n");
  634. X        WaitClose();
  635. X    }
  636. X    CleanUp();
  637. X#endif
  638. X    mode(0);
  639. X    if (exitcode && !Zmodem)        /* bellow again with all thy might. */
  640. X        canit();
  641. X    exit(exitcode);
  642. X}
  643. X
  644. X#ifdef AMIGA
  645. Xchar *babble[] = {
  646. X    "Usage:  rz [-BIYabehmnv]            (ZMODEM Batch)",
  647. X    "or      rb [-Iabhv]             (YMODEM Batch)",
  648. X    "or      rz [-Iabchv] file        (XMODEM or XMODEM-1k)",
  649. X    "          -I Initialize serial port, using zmodem.init file",
  650. X    "          -B Force Ymodem Batch transfer",
  651. X    "          -a ASCII transfer (strip CR)",
  652. X    "          -b Binary transfer for all files",
  653. X    "          -c Use 16 bit CRC     (XMODEM)",
  654. X    "          -e Ignore control characters  (ZMODEM)",
  655. X    "          -h Half duplex mode (only for Terminal mode)",
  656. X    "          -m Don't set file modes",
  657. X    "          -n No skipping over files even if to large for disk",
  658. X    "          -Q Quit without waiting for click in close box",
  659. X    "          -T enter Terminal mode before transferring",
  660. X    "          -v Verbose more v's give more info",
  661. X    ""
  662. X};
  663. X
  664. Xusage()
  665. X{
  666. X  char **pp;
  667. X  int i,n,rows,cols,height;
  668. X  struct Screen Scr;
  669. X  char rep[20];
  670. X
  671. X    /* Expand window, to show as many lines at once as possible */
  672. X    MoveWindow(Win,-Win->LeftEdge,-Win->TopEdge);
  673. X    if( !GetScreenData(&Scr,sizeof(struct Screen),WBENCHSCREEN)) {
  674. X    fprintf(stderr,"Couldn't get screen size");
  675. X    CleanUp();
  676. X    exit(1);
  677. X    }
  678. X    rows=Scr.Height;
  679. X    cols=Scr.Width;
  680. X    SizeWindow(Win,cols>640?640-Win->Width:cols-Win->Width,
  681. X           rows-Win->Height);
  682. X    Delay(15);  /* Wait until window is resized */
  683. X    ConPutStr(ConWriteReq,"\2330 q"); /* get window bounds */
  684. X    n = 0;
  685. X    while((rep[n] = ConGetC(ConReadReq)) != 'r' && n++ < 20)
  686. X    ;
  687. X    height=0;
  688. X    i=5;
  689. X    while(rep[i]>='0' && rep[i]<='9' && i<n) {
  690. X    height*=10;
  691. X    height+=rep[i++]-'0';
  692. X    }
  693. X    for (pp=babble,i=1; **pp; ++pp,i++) {
  694. X    fprintf(stderr, "%s\n", *pp);
  695. X    if((i%height)==(height-1)) {
  696. X        WaitKey();
  697. X        ConPutStr(ConWriteReq,"\2331\0731\110\233\112");  /* Erase screen */
  698. X    }
  699. X    }
  700. X    fprintf(stderr,"%s by Chuck Forsberg, amiga version 1.0 by Frank Harper\n",VERSION);
  701. X    WaitKey();
  702. X    bibi(1);
  703. X}
  704. X
  705. XWaitKey()
  706. X{
  707. X  char ConChar;
  708. X  ULONG mask,IntuiMask,ConInMask;
  709. X
  710. X    IntuiMask = 1 << (Win->UserPort->mp_SigBit);
  711. X    ConInMask = 1 << (ConReadPort->mp_SigBit);
  712. X    ConPutStr(ConWriteReq,"\23307\155 Press a key \23300\155");
  713. X    QueueRead(ConReadReq,&ConChar);
  714. X    mask=Wait(ConInMask|IntuiMask);
  715. X    puts("Got something");
  716. X    if(CheckQuit()) {       /* Hit close box? */
  717. X    KillIO(ConReadReq);
  718. X    bibi(1);
  719. X    }
  720. X    GetMsg(ConReadPort);
  721. X}
  722. X#else
  723. Xusage()
  724. X{
  725. X    fprintf(stderr,"%s %s for %s by Chuck Forsberg\n",
  726. X      Progname, VERSION, OS);
  727. X    fprintf(stderr,"Usage:  rz [-1abeuv]            (ZMODEM Batch)\n");
  728. X    fprintf(stderr,"or      rb [-1abuv]             (YMODEM Batch)\n");
  729. X    fprintf(stderr,"or      rx [-1abcv] file        (XMODEM or XMODEM-1k)\n");
  730. X    fprintf(stderr,"          -1 For cu(1): Use fd 1 for input\n");
  731. X    fprintf(stderr,"          -a ASCII transfer (strip CR)\n");
  732. X    fprintf(stderr,"          -b Binary transfer for all files\n");
  733. X    fprintf(stderr,"          -c Use 16 bit CRC     (XMODEM)\n");
  734. X    fprintf(stderr,"          -e Ignore control characters  (ZMODEM)\n");
  735. X    fprintf(stderr,"          -v Verbose more v's give more info\n");
  736. X    exit(1);
  737. X}
  738. X#endif
  739. X/*
  740. X *  Debugging information output interface routine
  741. X */
  742. X/* VARARGS1 */
  743. Xvfile(f, a, b, c)
  744. Xregister char *f;
  745. X{
  746. X    if (Verbose > 2) {
  747. X        fprintf(stderr, f, a, b, c);
  748. X        fprintf(stderr, "\n");
  749. X    }
  750. X}
  751. X
  752. X/*
  753. X * Let's receive something already.
  754. X */
  755. X
  756. Xchar *rbmsg =
  757. X"%s ready. To begin transfer, type \"%s file ...\" to your modem program\r\n";
  758. X
  759. Xwcreceive(argc, argp)
  760. Xchar **argp;
  761. X{
  762. X    register c;
  763. X
  764. X    if (Batch || argc==0) {
  765. X        Crcflg=(Wcsmask==0377);
  766. X        if ( !Quiet)
  767. X            fprintf(stderr, rbmsg, Progname, Nozmodem?"sb":"sz");
  768. X        if (c=tryz()) {
  769. X            if (c == ZCOMPL)
  770. X                return OK;
  771. X            if (c == ERROR)
  772. X                goto fubar;
  773. X            c = rzfiles();
  774. X            if (c)
  775. X                goto fubar;
  776. X        } else {
  777. X            for (;;) {
  778. X                if (wcrxpn(secbuf)== ERROR)
  779. X                    goto fubar;
  780. X                if (secbuf[0]==0)
  781. X                    return OK;
  782. X                if (procheader(secbuf) == ERROR)
  783. X                    goto fubar;
  784. X                if (wcrx()==ERROR)
  785. X                    goto fubar;
  786. X            }
  787. X        }
  788. X    } else {
  789. X        Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
  790. X
  791. X        procheader(""); strcpy(Pathname, *argp);
  792. X#ifndef AMIGA
  793. X        checkpath(Pathname);
  794. X#endif
  795. X        fprintf(stderr, "\nrz: ready to receive %s\r\n", Pathname);
  796. X        if ((fout=fopen(Pathname, "w")) == NULL)
  797. X            return ERROR;
  798. X        if (wcrx()==ERROR)
  799. X            goto fubar;
  800. X    }
  801. X    return OK;
  802. Xfubar:
  803. X    canit();
  804. X#ifndef AMIGA
  805. X    if (Topipe && fout) {
  806. X        pclose(fout);  return ERROR;
  807. X    }
  808. X#endif
  809. X    if (fout)
  810. X        fclose(fout);
  811. X    if (Restricted) {
  812. X        unlink(Pathname);
  813. X        fprintf(stderr, "\r\nrz: %s removed.\r\n", Pathname);
  814. X    }
  815. X    return ERROR;
  816. X}
  817. X
  818. X
  819. X/*
  820. X * Fetch a pathname from the other end as a C ctyle ASCIZ string.
  821. X * Length is indeterminate as long as less than Blklen
  822. X * A null string represents no more files (YMODEM)
  823. X */
  824. Xwcrxpn(rpn)
  825. Xchar *rpn;    /* receive a pathname */
  826. X{
  827. X    register c;
  828. X
  829. X#ifdef NFGVMIN
  830. X    readline(1);
  831. X#else
  832. X    purgeline();
  833. X#endif
  834. X
  835. Xet_tu:
  836. X    Firstsec=TRUE;    Eofseen=FALSE;
  837. X    sendline(Crcflg?WANTCRC:NAK);
  838. X    Lleft=0;    /* Do read next time ... */
  839. X    while ((c = wcgetsec(rpn, 100)) != 0) {
  840. X        if (c == WCEOT) {
  841. X            zperr( "Pathname fetch returned %d", c);
  842. X            sendline(ACK);
  843. X            Lleft=0;    /* Do read next time ... */
  844. X            readline(1);
  845. X            goto et_tu;
  846. X        }
  847. X        return ERROR;
  848. X    }
  849. X    sendline(ACK);
  850. X    return OK;
  851. X}
  852. X
  853. X/*
  854. X * Adapted from CMODEM13.C, written by
  855. X * Jack M. Wierda and Roderick W. Hart
  856. X */
  857. X
  858. Xwcrx()
  859. X{
  860. X    register int sectnum, sectcurr;
  861. X    register char sendchar;
  862. X    register char *p;
  863. X    int cblklen;            /* bytes to dump this block */
  864. X
  865. X    Firstsec=TRUE;sectnum=0; Eofseen=FALSE;
  866. X    sendchar=Crcflg?WANTCRC:NAK;
  867. X
  868. X    for (;;) {
  869. X        sendline(sendchar);     /* send it now, we're ready! */
  870. X        Lleft=0;    /* Do read next time ... */
  871. X        sectcurr=wcgetsec(secbuf, (sectnum&0177)?50:130);
  872. X        report(sectcurr);
  873. X        if (sectcurr==(sectnum+1 &Wcsmask)) {
  874. X            sectnum++;
  875. X            cblklen = Bytesleft>Blklen ? Blklen:Bytesleft;
  876. X            if (putsec(secbuf, cblklen)==ERROR)
  877. X                return ERROR;
  878. X            if ((Bytesleft-=cblklen) < 0)
  879. X                Bytesleft = 0;
  880. X            sendchar=ACK;
  881. X        }
  882. X        else if (sectcurr==(sectnum&Wcsmask)) {
  883. X            zperr( "Received dup Sector");
  884. X            sendchar=ACK;
  885. X        }
  886. X        else if (sectcurr==WCEOT) {
  887. X            if (closeit())
  888. X                return ERROR;
  889. X            sendline(ACK);
  890. X            Lleft=0;    /* Do read next time ... */
  891. X            return OK;
  892. X        }
  893. X        else if (sectcurr==ERROR)
  894. X            return ERROR;
  895. X        else {
  896. X            zperr( "Sync Error");
  897. X            return ERROR;
  898. X        }
  899. X    }
  900. X}
  901. X
  902. X/*
  903. X * Wcgetsec fetches a Ward Christensen type sector.
  904. X * Returns sector number encountered or ERROR if valid sector not received,
  905. X * or CAN CAN received
  906. X * or WCEOT if eot sector
  907. X * time is timeout for first char, set to 4 seconds thereafter
  908. X ***************** NO ACK IS SENT IF SECTOR IS RECEIVED OK **************
  909. X *    (Caller must do that when he is good and ready to get next sector)
  910. X */
  911. X
  912. Xwcgetsec(rxbuf, maxtime)
  913. Xchar *rxbuf;
  914. Xint maxtime;
  915. X{
  916. X    register checksum, wcj, firstch;
  917. X    register unsigned short oldcrc;
  918. X    register char *p;
  919. X    int sectcurr;
  920. X
  921. X    for (Lastrx=errors=0; errors<RETRYMAX; errors++) {
  922. X
  923. X        if ((firstch=readline(maxtime))==STX) {
  924. X            Blklen=KSIZE; goto get2;
  925. X        }
  926. X        if (firstch==SOH) {
  927. X            Blklen=SECSIZ;
  928. Xget2:
  929. X            sectcurr=readline(1);
  930. X            if ((sectcurr+(oldcrc=readline(1)))==Wcsmask) {
  931. X                oldcrc=checksum=0;
  932. X                for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {
  933. X                    if ((firstch=readline(1)) < 0)
  934. X                        goto bilge;
  935. X                    oldcrc=updcrc(firstch, oldcrc);
  936. X                    checksum += (*p++ = firstch);
  937. X                }
  938. X                if ((firstch=readline(1)) < 0)
  939. X                    goto bilge;
  940. X                if (Crcflg) {
  941. X                    oldcrc=updcrc(firstch, oldcrc);
  942. X                    if ((firstch=readline(1)) < 0)
  943. X                        goto bilge;
  944. X                    oldcrc=updcrc(firstch, oldcrc);
  945. X                    if (oldcrc & 0xFFFF)
  946. X                        zperr( "CRC");
  947. X                    else {
  948. X                        Firstsec=FALSE;
  949. X                        return sectcurr;
  950. X                    }
  951. X                }
  952. X                else if (((checksum-firstch)&Wcsmask)==0) {
  953. X                    Firstsec=FALSE;
  954. X                    return sectcurr;
  955. X                }
  956. X                else
  957. X                    zperr( "Checksum");
  958. X            }
  959. X            else
  960. X                zperr("Sector number garbled");
  961. X        }
  962. X        /* make sure eot really is eot and not just mixmash */
  963. X#ifdef NFGVMIN
  964. X        else if (firstch==EOT && readline(1)==TIMEOUT)
  965. X            return WCEOT;
  966. X#else
  967. X        else if (firstch==EOT && Lleft==0)
  968. X            return WCEOT;
  969. X#endif
  970. X        else if (firstch==CAN) {
  971. X            if (Lastrx==CAN) {
  972. X                zperr( "Sender CANcelled");
  973. X                return ERROR;
  974. X            } else {
  975. X                Lastrx=CAN;
  976. X                continue;
  977. X            }
  978. X        }
  979. X        else if (firstch==TIMEOUT) {
  980. X            if (Firstsec)
  981. X                goto humbug;
  982. Xbilge:
  983. X            zperr( "TIMEOUT");
  984. X        }
  985. X        else
  986. X            zperr( "Got 0%o sector header", firstch);
  987. X
  988. Xhumbug:
  989. X        Lastrx=0;
  990. X        while(readline(1)!=TIMEOUT)
  991. X            ;
  992. X        if (Firstsec) {
  993. X            sendline(Crcflg?WANTCRC:NAK);
  994. X            Lleft=0;    /* Do read next time ... */
  995. X        } else {
  996. X            maxtime=40; sendline(NAK);
  997. X            Lleft=0;    /* Do read next time ... */
  998. X        }
  999. X    }
  1000. X    /* try to stop the bubble machine. */
  1001. X    canit();
  1002. X    return ERROR;
  1003. X}
  1004. X#ifndef AMIGA
  1005. X/*
  1006. X * This version of readline is reasoably well suited for
  1007. X * reading many characters.
  1008. X *  (except, currently, for the Regulus version!)
  1009. X *
  1010. X * timeout is in tenths of seconds
  1011. X */
  1012. Xreadline(timeout)
  1013. Xint timeout;
  1014. X{
  1015. X    register n;
  1016. X    static char *cdq;    /* pointer for removing chars from linbuf */
  1017. X
  1018. X    if (--Lleft >= 0) {
  1019. X        if (Verbose > 8) {
  1020. X            fprintf(stderr, "%02x ", *cdq&0377);
  1021. X        }
  1022. X        return (*cdq++ & Wcsmask);
  1023. X    }
  1024. X    n = timeout/10;
  1025. X    if (n < 2)
  1026. X        n = 3;
  1027. X    if (Verbose > 5)
  1028. X        fprintf(stderr, "Calling read: alarm=%d  Readnum=%d ",
  1029. X          n, Readnum);
  1030. X    if (setjmp(tohere)) {
  1031. X#ifdef TIOCFLUSH
  1032. X/*        ioctl(iofd, TIOCFLUSH, 0); */
  1033. X#endif
  1034. X        Lleft = 0;
  1035. X        if (Verbose>1)
  1036. X            fprintf(stderr, "Readline:TIMEOUT\n");
  1037. X        return TIMEOUT;
  1038. X    }
  1039. X    signal(SIGALRM, alrm); alarm(n);
  1040. X    Lleft=read(iofd, cdq=linbuf, Readnum);
  1041. X    alarm(0);
  1042. X    if (Verbose > 5) {
  1043. X        fprintf(stderr, "Read returned %d bytes\n", Lleft);
  1044. X    }
  1045. X    if (Lleft < 1)
  1046. X        return TIMEOUT;
  1047. X    --Lleft;
  1048. X    if (Verbose > 8) {
  1049. X        fprintf(stderr, "%02x ", *cdq&0377);
  1050. X    }
  1051. X    return (*cdq++ & Wcsmask);
  1052. X}
  1053. X#else
  1054. Xreadline(timeout)
  1055. Xint timeout;
  1056. X{
  1057. X   int c;
  1058. X
  1059. X   c = ReadSer(timeout);
  1060. X   if(c<0)
  1061. X    {
  1062. X    switch(c) {
  1063. X
  1064. X      case TIMEOUT:
  1065. X            Lleft = 0;
  1066. X            if (Verbose>1)
  1067. X                fprintf(stderr, "Readline:TIMEOUT\n");
  1068. X            return TIMEOUT;
  1069. X
  1070. X      default:if(Verbose) fprintf(stderr,"readline: unknown error\n");
  1071. X          return -1;break;
  1072. X    }
  1073. X     }
  1074. X   else { if(Verbose>8) fprintf(stderr,"%02x ",c&0377);
  1075. X       return(c&Wcsmask);
  1076. X    }
  1077. X}
  1078. X
  1079. X#endif /* ifndef AMIGA */
  1080. X
  1081. X
  1082. X/*
  1083. X * Purge the modem input queue of all characters
  1084. X */
  1085. Xpurgeline()
  1086. X{
  1087. X    Lleft = 0;
  1088. X#ifdef AMIGA
  1089. X    PurgeSer();
  1090. X#else
  1091. X#ifdef USG
  1092. X    ioctl(iofd, TCFLSH, 0);
  1093. X#else
  1094. X    lseek(iofd, 0L, 2);
  1095. X#endif
  1096. X#endif /* AMIGA */
  1097. X}
  1098. X
  1099. X/*
  1100. X * Process incoming file information header
  1101. X */
  1102. Xprocheader(name)
  1103. Xchar *name;
  1104. X{
  1105. X    register char *openmode, *p, **pp;
  1106. X
  1107. X    /* set default parameters and overrides */
  1108. X    openmode = "w";
  1109. X    Thisbinary = (!Rxascii) || Rxbinary;
  1110. X    if (Lzmanag)
  1111. X        zmanag = Lzmanag;
  1112. X
  1113. X    /*
  1114. X     *  Process ZMODEM remote file management requests
  1115. X     */
  1116. X    if (!Rxbinary && zconv == ZCNL) /* Remote ASCII override */
  1117. X        Thisbinary = 0;
  1118. X    if (zconv == ZCBIN)     /* Remote Binary override */
  1119. X        Thisbinary = TRUE;
  1120. X    else if (zmanag == ZMAPND)
  1121. X        openmode = "a";
  1122. X
  1123. X#ifndef BIX
  1124. X    /* ZMPROT check for existing file */
  1125. X    if (zmanag == ZMPROT && (fout=fopen(name, "r"))) {
  1126. X        fclose(fout);  return ERROR;
  1127. X    }
  1128. X#endif
  1129. X
  1130. X    Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;
  1131. X
  1132. X    p = name + 1 + strlen(name);
  1133. X    if (*p) {       /* file coming from Unix or DOS system */
  1134. X        sscanf(p, "%ld%lo%o", &Bytesleft, &Modtime, &Filemode);
  1135. X#ifndef AMIGA  /* if the user wants ascii conversion give it to him
  1136. X          even if file is coming from UNIX */
  1137. X        if (Filemode & UNIXFILE)
  1138. X            ++Thisbinary;
  1139. X#endif
  1140. X        if (Verbose) {
  1141. X#ifndef AMIGA
  1142. X            fprintf(stderr,  "Incoming: %s %ld %lo %o\n",
  1143. X              name, Bytesleft, Modtime, Filemode);
  1144. X#else
  1145. X            fprintf(stderr,  "\nIncoming: %s length=%ld\n",
  1146. X              name, Bytesleft); /* Trying to be a little less
  1147. X                        cryptic than the UNIX version*/
  1148. X#endif
  1149. X        }
  1150. X    }
  1151. X
  1152. X#ifdef BIX
  1153. X    if ((fout=fopen("scratchpad", openmode)) == NULL)
  1154. X        return ERROR;
  1155. X    return OK;
  1156. X#else
  1157. X
  1158. X    else {        /* File coming from CP/M system */
  1159. X        for (p=name; *p; ++p)           /* change / to _ */
  1160. X            if ( *p == '/')
  1161. X                *p = '_';
  1162. X
  1163. X        if ( *--p == '.')               /* zap trailing period */
  1164. X            *p = 0;
  1165. X    }
  1166. X
  1167. X    if (!Zmodem && MakeLCPathname && !IsAnyLower(name))
  1168. X        uncaps(name);
  1169. X    if (Topipe) {
  1170. X#ifndef AMIGA
  1171. X        sprintf(Pathname, "%s %s", Progname+2, name);
  1172. X        if (Verbose)
  1173. X            fprintf(stderr,  "Topipe: %s %s\n",
  1174. X              Pathname, Thisbinary?"BIN":"ASCII");
  1175. X        if ((fout=popen(Pathname, "w")) == NULL)
  1176. X            return ERROR;
  1177. X#endif
  1178. X    } else {
  1179. X        strcpy(Pathname, name);
  1180. X#ifndef AMIGA
  1181. X        if (Verbose) {
  1182. X            fprintf(stderr,  "Receiving %s %s %s\n",
  1183. X              name, Thisbinary?"BIN":"ASCII", openmode);
  1184. X        }
  1185. X        checkpath(name);
  1186. X#else
  1187. X        if (Verbose) {
  1188. X            fprintf(stderr,  "file transfer mode is %s, file open mode is %s\n",
  1189. X              Thisbinary?"BIN":"ASCII", openmode);
  1190. X        }
  1191. X#endif
  1192. X        if (Nflag)
  1193. X            name = "/dev/null";
  1194. X        if ((fout=fopen(name, openmode)) == NULL)
  1195. X            return ERROR;
  1196. X    }
  1197. X    return OK;
  1198. X#endif /* BIX */
  1199. X}
  1200. X
  1201. X/*
  1202. X * Putsec writes the n characters of buf to receive file fout.
  1203. X *  If not in binary mode, carriage returns, and all characters
  1204. X *  starting with CPMEOF are discarded.
  1205. X */
  1206. Xputsec(buf, n)
  1207. Xchar *buf;
  1208. Xregister n;
  1209. X{
  1210. X    register char *p;
  1211. X
  1212. X    if (Thisbinary) {
  1213. X        for (p=buf; --n>=0; )
  1214. X            if( putc( *p++, fout)==EOF )
  1215. X                return ERROR;
  1216. X    }
  1217. X    else {
  1218. X        if (Eofseen)
  1219. X            return OK;
  1220. X        for (p=buf; --n>=0; ++p ) {
  1221. X            if ( *p == '\r')
  1222. X                continue;
  1223. X            if (*p == CPMEOF) {
  1224. X                Eofseen=TRUE; return OK;
  1225. X            }
  1226. X            if( putc(*p ,fout)==EOF )
  1227. X                return ERROR;
  1228. X        }
  1229. X    }
  1230. X    return OK;
  1231. X}
  1232. X
  1233. X#ifndef AMIGA
  1234. X/*
  1235. X *  Send a character to modem.    Small is beautiful.
  1236. X */
  1237. Xsendline(c)
  1238. X{
  1239. X    char d;
  1240. X
  1241. X    d = c;
  1242. X    if (Verbose>6)
  1243. X        fprintf(stderr, "Sendline: %x\n", c);
  1244. X    write(1, &d, 1);
  1245. X}
  1246. X#else
  1247. Xsendline(c)
  1248. Xint c;
  1249. X{
  1250. X  char d;
  1251. X  int retc;
  1252. X
  1253. X  d=c;
  1254. X  if(Verbose>6)
  1255. X    fprintf(stderr,"S:%02x\n",c);
  1256. X  if( (retc=LWriteSer(&d,1))!=0 )
  1257. X      if(Verbose) fprintf(stderr,"sendline:Error sending character %d\n",retc);
  1258. X}
  1259. X#endif
  1260. X
  1261. Xxsendline(c)
  1262. X{
  1263. X    sendline(c);
  1264. X}
  1265. X
  1266. Xflushmo() {}
  1267. X
  1268. X
  1269. X
  1270. X
  1271. X/* make string s lower case */
  1272. Xuncaps(s)
  1273. Xregister char *s;
  1274. X{
  1275. X    for ( ; *s; ++s)
  1276. X        if (isupper(*s))
  1277. X            *s = tolower(*s);
  1278. X}
  1279. X/*
  1280. X * IsAnyLower returns TRUE if string s has lower case letters.
  1281. X */
  1282. XIsAnyLower(s)
  1283. Xregister char *s;
  1284. X{
  1285. X    for ( ; *s; ++s)
  1286. X        if (islower(*s))
  1287. X            return TRUE;
  1288. X    return FALSE;
  1289. X}
  1290. X
  1291. X/*
  1292. X * substr(string, token) searches for token in string s
  1293. X * returns pointer to token within string if found, NULL otherwise
  1294. X */
  1295. Xchar *
  1296. Xsubstr(s, t)
  1297. Xregister char *s,*t;
  1298. X{
  1299. X    register char *ss,*tt;
  1300. X    /* search for first char of token */
  1301. X    for (ss=s; *s; s++)
  1302. X        if (*s == *t)
  1303. X            /* compare token with substring */
  1304. X            for (ss=s,tt=t; ;) {
  1305. X                if (*tt == 0)
  1306. X                    return s;
  1307. X                if (*ss++ != *tt++)
  1308. X                    break;
  1309. X            }
  1310. X    return NULL;
  1311. X}
  1312. X
  1313. X/*
  1314. X * Log an error
  1315. X */
  1316. X/*VARARGS1*/
  1317. Xzperr(s,p,u)
  1318. Xchar *s, *p, *u;
  1319. X{
  1320. X    if (Verbose <= 0)
  1321. X        return;
  1322. X    fprintf(stderr, "Retry %d: ", errors);
  1323. X    fprintf(stderr, s, p, u);
  1324. X    fprintf(stderr, "\n");
  1325. X}
  1326. X
  1327. X/* send cancel string to get the other end to shut up */
  1328. Xcanit()
  1329. X{
  1330. X    static char canistr[] = {
  1331. X     24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
  1332. X    };
  1333. X#ifndef AMIGA
  1334. X    printf(canistr);
  1335. X#else
  1336. X    LWriteSer(canistr,strlen(canistr));
  1337. X#endif
  1338. X    Lleft=0;    /* Do read next time ... */
  1339. X    fflush(stdout);
  1340. X}
  1341. X
  1342. X#ifndef AMIGA
  1343. X/*
  1344. X * Return 1 iff stdout and stderr are different devices
  1345. X *  indicating this program operating with a modem on a
  1346. X *  different line
  1347. X */
  1348. Xfromcu()
  1349. X{
  1350. X    struct stat a, b;
  1351. X    fstat(1, &a); fstat(2, &b);
  1352. X    return (a.st_rdev != b.st_rdev);
  1353. X}
  1354. X#else /* AMIGA */
  1355. Xfromcu()
  1356. X{
  1357. X return TRUE;
  1358. X}
  1359. X#endif
  1360. X
  1361. Xreport(sct)
  1362. Xint sct;
  1363. X{
  1364. X    if (Verbose>1)
  1365. X        fprintf(stderr,"%03d%c",sct,sct%10? ' ' : '\r');
  1366. X}
  1367. X
  1368. X/*
  1369. X * If called as [-][dir/../]vrzCOMMAND set Verbose to 1
  1370. X * If called as [-][dir/../]rzCOMMAND set the pipe flag
  1371. X * If called as rb use YMODEM protocol
  1372. X */
  1373. Xchkinvok(s)
  1374. Xchar *s;
  1375. X{
  1376. X    register char *p;
  1377. X
  1378. X    p = s;
  1379. X    while (*p == '-')
  1380. X        s = ++p;
  1381. X    while (*p)
  1382. X        if (*p++ == '/')
  1383. X            s = p;
  1384. X    if (*s == 'v') {
  1385. X        Verbose=1; ++s;
  1386. X    }
  1387. X    Progname = s;
  1388. X    if (s[0]=='r' && s[1]=='b')
  1389. X        Nozmodem = TRUE;
  1390. X#ifndef AMIGA
  1391. X    if (s[2] && s[0]=='r' && s[1]=='b')
  1392. X        Topipe=TRUE;
  1393. X    if (s[2] && s[0]=='r' && s[1]=='z')
  1394. X        Topipe=TRUE;
  1395. X#endif
  1396. X}
  1397. X
  1398. X#ifndef AMIGA
  1399. X/*
  1400. X * Totalitarian Communist pathname processing
  1401. X */
  1402. Xcheckpath(name)
  1403. Xchar *name;
  1404. X{
  1405. X    if (Restricted) {
  1406. X        if (fopen(name, "r") != NULL) {
  1407. X            canit();
  1408. X            fprintf(stderr, "\r\nrz: %s exists\n", name);
  1409. X            bibi(-1);
  1410. X        }
  1411. X        /* restrict pathnames to current tree or uucppublic */
  1412. X        if ( substr(name, "../")
  1413. X         || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) {
  1414. X            canit();
  1415. X            fprintf(stderr,"\r\nrz:\tSecurity Violation\r\n");
  1416. X            bibi(-1);
  1417. X        }
  1418. X    }
  1419. X}
  1420. X#endif
  1421. X/*
  1422. X * Initialize for Zmodem receive attempt, try to activate Zmodem sender
  1423. X *  Handles ZSINIT frame
  1424. X *  Return ZFILE if Zmodem filename received, -1 on error,
  1425. X *   ZCOMPL if transaction finished,  else 0
  1426. X */
  1427. Xtryz()
  1428. X{
  1429. X    register c, n;
  1430. X    register cmdzack1flg;
  1431. X
  1432. X    if (Nozmodem)           /* Check for "rb" program name */
  1433. X        return 0;
  1434. X
  1435. X
  1436. X    for (n=Zmodem?15:5; --n>=0; ) {
  1437. X        /* Set buffer length (0) and capability flags */
  1438. X        stohdr(0L);
  1439. X#ifdef CANBREAK
  1440. X        Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
  1441. X#else
  1442. X        Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;
  1443. X#endif
  1444. X        if (Zctlesc)
  1445. X            Txhdr[ZF0] |= TESCCTL;
  1446. X        zshhdr(tryzhdrtype, Txhdr);
  1447. X        if (tryzhdrtype == ZSKIP)       /* Don't skip too far */
  1448. X            tryzhdrtype = ZRINIT;    /* CAF 8-21-87 */
  1449. Xagain:
  1450. X        switch (zgethdr(Rxhdr, 0)) {
  1451. X        case ZRQINIT:
  1452. X            continue;
  1453. X        case ZEOF:
  1454. X            continue;
  1455. X        case TIMEOUT:
  1456. X            continue;
  1457. X        case ZFILE:
  1458. X            zconv = Rxhdr[ZF0];
  1459. X            zmanag = Rxhdr[ZF1];
  1460. X            ztrans = Rxhdr[ZF2];
  1461. X            tryzhdrtype = ZRINIT;
  1462. X            c = zrdata(secbuf, KSIZE);
  1463. X            mode(3);
  1464. X            if (c == GOTCRCW)
  1465. X                return ZFILE;
  1466. X            zshhdr(ZNAK, Txhdr);
  1467. X            goto again;
  1468. X        case ZSINIT:
  1469. X            Zctlesc = TESCCTL & Rxhdr[ZF0];
  1470. X            if (zrdata(Attn, ZATTNLEN) == GOTCRCW) {
  1471. X                zshhdr(ZACK, Txhdr);
  1472. X                goto again;
  1473. X            }
  1474. X            zshhdr(ZNAK, Txhdr);
  1475. X            goto again;
  1476. X        case ZFREECNT:
  1477. X            stohdr(getfree());
  1478. X            zshhdr(ZACK, Txhdr);
  1479. X            goto again;
  1480. X        case ZCOMMAND:
  1481. X            cmdzack1flg = Rxhdr[ZF0];
  1482. X            if (zrdata(secbuf, KSIZE) == GOTCRCW) {
  1483. X                if (cmdzack1flg & ZCACK1)
  1484. X                    stohdr(0L);
  1485. X                else
  1486. X                    stohdr((long)sys2(secbuf));
  1487. X                purgeline();    /* dump impatient questions */
  1488. X                do {
  1489. X                    zshhdr(ZCOMPL, Txhdr);
  1490. X                }
  1491. X                while (++errors<20 && zgethdr(Rxhdr,1) != ZFIN);
  1492. X                ackbibi();
  1493. X                if (cmdzack1flg & ZCACK1)
  1494. X                    exec2(secbuf);
  1495. X                return ZCOMPL;
  1496. X            }
  1497. X            zshhdr(ZNAK, Txhdr); goto again;
  1498. X        case ZCOMPL:
  1499. X            goto again;
  1500. X        default:
  1501. X            continue;
  1502. X        case ZFIN:
  1503. X            ackbibi(); return ZCOMPL;
  1504. X        case ZCAN:
  1505. X            return ERROR;
  1506. X        }
  1507. X    }
  1508. X    return 0;
  1509. X}
  1510. X
  1511. X/*
  1512. X * Receive 1 or more files with ZMODEM protocol
  1513. X */
  1514. Xrzfiles()
  1515. X{
  1516. X    register c;
  1517. X
  1518. X    for (;;) {
  1519. X        switch (c = rzfile()) {
  1520. X        case ZEOF:
  1521. X        case ZSKIP:
  1522. X            switch (tryz()) {
  1523. X            case ZCOMPL:
  1524. X                return OK;
  1525. X            default:
  1526. X                return ERROR;
  1527. X            case ZFILE:
  1528. X                break;
  1529. X            }
  1530. X            continue;
  1531. X        default:
  1532. X            return c;
  1533. X        case ERROR:
  1534. X            return ERROR;
  1535. X        }
  1536. X    }
  1537. X}
  1538. X
  1539. X/*
  1540. X * Receive a file with ZMODEM protocol
  1541. X *  Assumes file name frame is in secbuf
  1542. X */
  1543. Xrzfile()
  1544. X{
  1545. X    register c, n;
  1546. X    long rxbytes;
  1547. X
  1548. X    Eofseen=FALSE;
  1549. X    if (procheader(secbuf) == ERROR) {
  1550. X        return (tryzhdrtype = ZSKIP);
  1551. X    }
  1552. X#ifdef AMIGA /* skip over file if it won't fit on disk */
  1553. X    if (Skip && Bytesleft!=DEFBYTL && Bytesleft>getfree()) {
  1554. X        fprintf(stderr,"rz:Not enough room left on disk for %s. (skipping it)\n",secbuf);
  1555. X        return (tryzhdrtype = ZSKIP);
  1556. X    }
  1557. X#endif
  1558. X    n = 20; rxbytes = 0l;
  1559. X
  1560. X    for (;;) {
  1561. X        stohdr(rxbytes);
  1562. X        zshhdr(ZRPOS, Txhdr);
  1563. Xnxthdr:
  1564. X        switch (c = zgethdr(Rxhdr, 0)) {
  1565. X        default:
  1566. X            vfile("rzfile: zgethdr returned %d", c);
  1567. X            return ERROR;
  1568. X        case ZNAK:
  1569. X        case TIMEOUT:
  1570. X            if ( --n < 0) {
  1571. X                vfile("rzfile: zgethdr returned %d", c);
  1572. X                return ERROR;
  1573. X            }
  1574. X        case ZFILE:
  1575. X            zrdata(secbuf, KSIZE);
  1576. X            continue;
  1577. X        case ZEOF:
  1578. X            if (rclhdr(Rxhdr) != rxbytes) {
  1579. X                /*
  1580. X                 * Ignore eof if it's at wrong place - force
  1581. X                 *  a timeout because the eof might have gone
  1582. X                 *  out before we sent our zrpos.
  1583. X                 */
  1584. X                errors = 0;  goto nxthdr;
  1585. X            }
  1586. X            if (closeit()) {
  1587. X                tryzhdrtype = ZFERR;
  1588. X                vfile("rzfile: closeit returned <> 0");
  1589. X                return ERROR;
  1590. X            }
  1591. X            vfile("rzfile: normal EOF");
  1592. X            return c;
  1593. X        case ERROR:    /* Too much garbage in header search error */
  1594. X            if ( --n < 0) {
  1595. X                vfile("rzfile: zgethdr returned %d", c);
  1596. X                return ERROR;
  1597. X            }
  1598. X            zmputs(Attn);
  1599. X            continue;
  1600. X        case ZDATA:
  1601. X            if (rclhdr(Rxhdr) != rxbytes) {
  1602. X                if ( --n < 0) {
  1603. X                    return ERROR;
  1604. X                }
  1605. X                zmputs(Attn);  continue;
  1606. X            }
  1607. Xmoredata:
  1608. X            if (Verbose>1)
  1609. X                fprintf(stderr, "\r%7ld ZMODEM%s    ",
  1610. X                  rxbytes, Crc32?" CRC-32":"");
  1611. X            switch (c = zrdata(secbuf, KSIZE)) {
  1612. X            case ZCAN:
  1613. X                vfile("rzfile: zgethdr returned %d", c);
  1614. X                return ERROR;
  1615. X            case ERROR:    /* CRC error */
  1616. X                if ( --n < 0) {
  1617. X                    vfile("rzfile: zgethdr returned %d", c);
  1618. X                    return ERROR;
  1619. X                }
  1620. X                zmputs(Attn);
  1621. X                continue;
  1622. X            case TIMEOUT:
  1623. X                if ( --n < 0) {
  1624. X                    vfile("rzfile: zgethdr returned %d", c);
  1625. X                    return ERROR;
  1626. X                }
  1627. X                continue;
  1628. X            case GOTCRCW:
  1629. X                n = 20;
  1630. X                putsec(secbuf, Rxcount);
  1631. X                rxbytes += Rxcount;
  1632. X                stohdr(rxbytes);
  1633. X                zshhdr(ZACK, Txhdr);
  1634. X                sendline(XON);
  1635. X                goto nxthdr;
  1636. X            case GOTCRCQ:
  1637. X                n = 20;
  1638. X                putsec(secbuf, Rxcount);
  1639. X                rxbytes += Rxcount;
  1640. X                stohdr(rxbytes);
  1641. X                zshhdr(ZACK, Txhdr);
  1642. X                goto moredata;
  1643. X            case GOTCRCG:
  1644. X                n = 20;
  1645. X                putsec(secbuf, Rxcount);
  1646. X                rxbytes += Rxcount;
  1647. X                goto moredata;
  1648. X            case GOTCRCE:
  1649. X                n = 20;
  1650. X                putsec(secbuf, Rxcount);
  1651. X                rxbytes += Rxcount;
  1652. X                goto nxthdr;
  1653. X            }
  1654. X        }
  1655. X    }
  1656. X}
  1657. X
  1658. X/*
  1659. X * Send a string to the modem, processing for \336 (sleep 1 sec)
  1660. X *   and \335 (break signal)
  1661. X */
  1662. Xzmputs(s)
  1663. Xchar *s;
  1664. X{
  1665. X    register c;
  1666. X
  1667. X    while (*s) {
  1668. X        switch (c = *s++) {
  1669. X        case '\336':
  1670. X            sleep(1); continue;
  1671. X        case '\335':
  1672. X            sendbrk(); continue;
  1673. X        default:
  1674. X            sendline(c);
  1675. X        }
  1676. X    }
  1677. X}
  1678. X
  1679. X/*
  1680. X * Close the receive dataset, return OK or ERROR
  1681. X */
  1682. Xcloseit()
  1683. X{
  1684. X#ifdef AMIGA
  1685. X    long attr;
  1686. X    int res;
  1687. X    struct DateStamp dss;
  1688. X    long time;
  1689. X#else
  1690. X    if (Topipe) {
  1691. X        if (pclose(fout)) {
  1692. X            return ERROR;
  1693. X        }
  1694. X        return OK;
  1695. X    }
  1696. X#endif
  1697. X    if (fclose(fout)==ERROR) {
  1698. X        fprintf(stderr, "file close ERROR\n");
  1699. X        return ERROR;
  1700. X    }
  1701. X#ifndef AMIGA
  1702. X    if (Modtime) {
  1703. X        timep[0] = time(NULL);
  1704. X        timep[1] = Modtime;
  1705. X        utime(Pathname, timep);
  1706. X    }
  1707. X    if (Filemode)
  1708. X        chmod(Pathname, (07777 & Filemode));
  1709. X#else
  1710. X    if (Modtime && gmt_diff_set) {
  1711. X        time=Modtime-(2*366+6*365)*24*60*60 +(gmt_diff * 60 * 60);
  1712. X        dss.ds_Tick=(time%60)*TICKS_PER_SECOND;
  1713. X        time/=60;
  1714. X        dss.ds_Minute=time%(60*24);
  1715. X        time/=60;
  1716. X        dss.ds_Days=time/24;
  1717. X        file_date(&dss,Pathname);
  1718. X    }
  1719. X    if (SetProtect && Filemode) {
  1720. X        /* Turn off flag to allow the action. */
  1721. X#ifndef FIBF_SCRIPT
  1722. X#define FIBF_SCRIPT (1 << 6)
  1723. X#endif
  1724. X#ifndef FIBF_PURE
  1725. X#define FIBF_PURE (1 << 5)
  1726. X#endif
  1727. X#ifndef FIBF_HIDDEN
  1728. X#define FIBF_HIDDEN (1 << 7)
  1729. X#endif
  1730. X        attr = 0L;
  1731. X        if(!(Filemode & 0400)) attr |= FIBF_READ;
  1732. X        if(!(Filemode & 0200)) attr |= (FIBF_WRITE | FIBF_DELETE);
  1733. X        if(!(Filemode & 0100)) attr |= FIBF_EXECUTE;
  1734. X        res=SetProtection(Pathname, attr);
  1735. X    }
  1736. X#endif
  1737. X    return OK;
  1738. X}
  1739. X
  1740. X/*
  1741. X * Ack a ZFIN packet, let byegones be byegones
  1742. X */
  1743. Xackbibi()
  1744. X{
  1745. X    register n;
  1746. X
  1747. X    vfile("ackbibi:");
  1748. X    Readnum = 1;
  1749. X    stohdr(0L);
  1750. X    for (n=3; --n>=0; ) {
  1751. X        purgeline();
  1752. X        zshhdr(ZFIN, Txhdr);
  1753. X        switch (readline(100)) {
  1754. X        case 'O':
  1755. X            readline(1);    /* Discard 2nd 'O' */
  1756. X            vfile("ackbibi complete");
  1757. X            return;
  1758. X        case RCDO:
  1759. X            return;
  1760. X        case TIMEOUT:
  1761. X        default:
  1762. X            break;
  1763. X        }
  1764. X    }
  1765. X}
  1766. X
  1767. X
  1768. X
  1769. X/*
  1770. X * Local console output simulation
  1771. X */
  1772. Xbttyout(c)
  1773. X{
  1774. X#ifndef AMIGA
  1775. X    if (Verbose || fromcu())
  1776. X#else
  1777. X    if (Verbose>2)
  1778. X#endif
  1779. X        putc(c, stderr);
  1780. X}
  1781. X
  1782. X#ifndef AMIGA
  1783. X/*
  1784. X * Strip leading ! if present, do shell escape.
  1785. X */
  1786. Xsys2(s)
  1787. Xregister char *s;
  1788. X{
  1789. X    if (*s == '!')
  1790. X        ++s;
  1791. X    return system(s);
  1792. X}
  1793. X/*
  1794. X * Strip leading ! if present, do exec.
  1795. X */
  1796. Xexec2(s)
  1797. Xregister char *s;
  1798. X{
  1799. X    if (*s == '!')
  1800. X        ++s;
  1801. X    mode(0);
  1802. X    execl("/bin/sh", "sh", "-c", s);
  1803. X}
  1804. X#else
  1805. Xsys2(s)
  1806. Xchar *s;
  1807. X{
  1808. X    if (*s == '!')
  1809. X        ++s;
  1810. X    /* if it's just an "echo" fake it */
  1811. X    if(strncmp(s,"echo",4)==0) { printf("%s\n",s+5);return 0; }
  1812. X    else return(!Execute(s,0L,0L));
  1813. X}
  1814. X
  1815. X
  1816. Xexec2(s)
  1817. Xchar *s;
  1818. X{
  1819. X  char cmdbuf[256]; /* Anybody like nice long commands? */
  1820. X
  1821. X    if (*s == '!')
  1822. X        ++s;
  1823. X    sprintf(cmdbuf,"run %s",s);
  1824. X    Execute(cmdbuf,0L,0L);
  1825. X}
  1826. X#endif
  1827. X/* End of rz.c */
  1828. SHAR_EOF
  1829. echo "End of archive 4 (of 9)"
  1830. # if you want to concatenate archives, remove anything after this line
  1831. exit
  1832.